﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Controls.Primitives;

namespace Silverlight.ControlToolkit
{
    [TemplatePart(Name = ExpandablePanel.RootElement, Type = typeof(FrameworkElement))]
    [TemplatePart(Name = ExpandablePanel.HeaderElement, Type = typeof(FrameworkElement))]
    [TemplatePart(Name = ExpandablePanel.HeaderTextElement, Type = typeof(FrameworkElement))]
    [TemplatePart(Name = ExpandablePanel.ContentHolderElement, Type = typeof(FrameworkElement))]
    [TemplatePart(Name = ExpandablePanel.ExpandAnimationStoryboard, Type = typeof(Storyboard))]
    [TemplatePart(Name = ExpandablePanel.CollapseAnimationStoryboard, Type = typeof(Storyboard))]
    public class ExpandablePanel : ContentControl
    {


        private const string RootElement = "RootElement";
        private const string HeaderElement = "HeaderElement";
        private const string HeaderTextElement = "HeaderTextElement";
        private const string ContentElement = "ContentElement";
        private const string ContentHolderElement = "ContentHolderElement";
        private const string ExpandAnimationStoryboard = "ExpandAnimationStoryboard";
        private const string CollapseAnimationStoryboard = "CollapseAnimationStoryboard";

        private FrameworkElement _rootElement;
        private FrameworkElement _headerElement;
        private FrameworkElement _headerTextElement;
        private FrameworkElement _contentHolderElement;
        private ContentPresenter _content;
        private Storyboard _expandAnimationStoryboard;
        private Storyboard _collapseAnimationStoryboard;

        public event RoutedEventHandler Expanded;
        public event RoutedEventHandler Collapsed;

        public ExpandablePanel()
            : base()
        {
            this.DefaultStyleKey = typeof(ExpandablePanel);
        }

        public static readonly DependencyProperty IsExpandedOnLoadProperty =
            DependencyProperty.Register("IsExpandedOnLoad", typeof(bool), typeof(ExpandablePanel),
                                new PropertyMetadata(new PropertyChangedCallback(IsExpandedOnLoadChangedCallback)));

        private static void IsExpandedOnLoadChangedCallback(DependencyObject obj,
                                DependencyPropertyChangedEventArgs args)
        {
            if (obj != null && ((ExpandablePanel)obj)._contentHolderElement != null && ((bool)args.NewValue) != (((ExpandablePanel)obj)._contentHolderElement.Visibility == Visibility.Visible))
                ((ExpandablePanel)obj).ToggleView();
        }

        public bool IsExpandedOnLoad
        {
            get
            {
                return (bool)GetValue(IsExpandedOnLoadProperty);
            }

            set
            {
                SetValue(IsExpandedOnLoadProperty, value);
            }
        }


        public static readonly DependencyProperty HeaderTextProperty =
            DependencyProperty.Register("HeaderText", typeof(string), typeof(ExpandablePanel),
                                new PropertyMetadata(new PropertyChangedCallback(HeaderTextChangedCallback)));

        private static void HeaderTextChangedCallback(DependencyObject obj,
                                DependencyPropertyChangedEventArgs args)
        {
            if (obj != null && ((ExpandablePanel)obj)._headerTextElement != null)
                ((ExpandablePanel)obj)._headerTextElement.SetValue(TextBlock.TextProperty, args.NewValue);
        }

        public string HeaderText
        {
            get
            {
                return (string)GetValue(HeaderTextProperty);
            }

            set
            {
                SetValue(HeaderTextProperty, value);
            }
        }


        public static readonly DependencyProperty HeaderForegroundProperty =
            DependencyProperty.Register("HeaderForeground", typeof(Brush), typeof(ExpandablePanel),
                                new PropertyMetadata(new PropertyChangedCallback(HeaderForegroundChangedCallback)));

        private static void HeaderForegroundChangedCallback(DependencyObject obj,
                                DependencyPropertyChangedEventArgs args)
        {
            if (obj != null && ((ExpandablePanel)obj)._headerTextElement != null)
                ((ExpandablePanel)obj)._headerTextElement.SetValue(TextBlock.ForegroundProperty, args.NewValue);
        }

        public Brush HeaderForeground
        {
            get
            {
                return (Brush)GetValue(HeaderForegroundProperty);
            }

            set
            {
                SetValue(HeaderForegroundProperty, value);
            }
        }


        public static readonly DependencyProperty HeaderBackgroundProperty =
            DependencyProperty.Register("HeaderBackground", typeof(Brush), typeof(ExpandablePanel),
                                new PropertyMetadata(new PropertyChangedCallback(HeaderBackgroundChangedCallback)));

        private static void HeaderBackgroundChangedCallback(DependencyObject obj,
                                DependencyPropertyChangedEventArgs args)
        {
            if (obj != null && ((ExpandablePanel)obj)._headerElement != null)
                ((ExpandablePanel)obj)._headerElement.SetValue(Border.BackgroundProperty, args.NewValue);
        }

        public Brush HeaderBackground
        {
            get
            {
                return (Brush)GetValue(HeaderBackgroundProperty);
            }

            set
            {
                SetValue(HeaderBackgroundProperty, value);
            }
        }


        public static readonly DependencyProperty HeaderFontSizeProperty =
            DependencyProperty.Register("HeaderFontSize", typeof(double), typeof(ExpandablePanel),
                                new PropertyMetadata(new PropertyChangedCallback(HeaderFontSizeChangedCallback)));

        private static void HeaderFontSizeChangedCallback(DependencyObject obj,
                                DependencyPropertyChangedEventArgs args)
        {
            if (obj != null && ((ExpandablePanel)obj)._headerTextElement != null)
                ((ExpandablePanel)obj)._headerTextElement.SetValue(TextBlock.FontSizeProperty, args.NewValue);
        }

        public double HeaderFontSize
        {
            get
            {
                return (double)GetValue(HeaderFontSizeProperty);
            }

            set
            {
                SetValue(HeaderFontSizeProperty, value);
            }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            _rootElement = (FrameworkElement)GetTemplateChild(ExpandablePanel.RootElement);
            _headerElement = (FrameworkElement)GetTemplateChild(ExpandablePanel.HeaderElement);
            _headerTextElement = (FrameworkElement)GetTemplateChild(ExpandablePanel.HeaderTextElement);
            _contentHolderElement = (FrameworkElement)GetTemplateChild(ExpandablePanel.ContentHolderElement);
            _content = (ContentPresenter)GetTemplateChild(ExpandablePanel.ContentElement);

            _expandAnimationStoryboard = (Storyboard)GetTemplateChild(ExpandablePanel.ExpandAnimationStoryboard);
            _collapseAnimationStoryboard = (Storyboard)GetTemplateChild(ExpandablePanel.CollapseAnimationStoryboard);


            if (_headerElement != null)
            {
                if (this.HeaderBackground != null)
                    _headerElement.SetValue(Border.BackgroundProperty, this.HeaderBackground);

                _headerElement.MouseLeftButtonDown += new MouseButtonEventHandler(_expandCollapseButton_MouseLeftButtonDown);

            }

            if (_headerTextElement != null)
            {
                if (this.HeaderText != null)
                    _headerTextElement.SetValue(TextBlock.TextProperty, this.HeaderText);

                if (this.HeaderForeground != null)
                    _headerTextElement.SetValue(TextBlock.ForegroundProperty, this.HeaderForeground);


                if (this.HeaderFontSize > 0)
                    _headerTextElement.SetValue(TextBlock.FontSizeProperty, this.HeaderFontSize);

            }

            if (_contentHolderElement != null && this.IsExpandedOnLoad)
                this.ToggleView();


            //if (_rootElement != null)
            //{
            //    _enter = (Storyboard)_rootElement.Resources[ExpandablePanel.MouseEnterAnimation];
            //    _leave = (Storyboard)_rootElement.Resources[ExpandablePanel.MouseLeaveAnimation];
            //}
        }

        void _expandCollapseButton_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.ToggleView();
        }

        public void Expand()
        {
            if (this._contentHolderElement.Visibility == Visibility.Collapsed)
                this.ToggleView();
        }

        public void Collapse()
        {
            if (this._contentHolderElement.Visibility == Visibility.Visible)
                this.ToggleView();
        }

        private void ToggleView()
        {
            if (this._contentHolderElement.Visibility == Visibility.Collapsed)
            {
                this._contentHolderElement.Visibility = Visibility.Visible;

                if (Expanded != null)
                    Expanded(this, new RoutedEventArgs());

                if (this._expandAnimationStoryboard != null)
                    this._expandAnimationStoryboard.Begin();

            }
            else
            {
                this._contentHolderElement.Visibility = Visibility.Collapsed;

                if (Collapsed != null)
                    Collapsed(this, new RoutedEventArgs());

                if (this._collapseAnimationStoryboard != null)
                    this._collapseAnimationStoryboard.Begin();

            }
        }




    }
}
